package org.xs.web.http.provider.servlet;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
 
import org.xs.web.http.XSRules;
import org.xs.web.http.provider.HTTPContext;
import org.xs.web.http.provider.HTTPCookie;
import org.xs.web.http.provider.HTTPRequest;
import org.xs.web.http.provider.HTTPSession;
import org.xs.web.http.provider.HTTPHeader;
import org.xs.web.util.Params;

 
public class HTTPServletRequest implements HTTPRequest{
	public static final Pattern htmlPattern = Pattern.compile("\\.html$|\\.htm$|\\.xhtml$");
	public static final Pattern jsonPattern = Pattern.compile("\\.json$");
	
	private HttpServletRequest delegate;
	private HTTPContext httpContext;
	private HTTPSession session;
	private List<HTTPCookie> httpCookies;
	private List<HTTPHeader> httpHeaders;
	private Map<String, Object> params ;
	private String trimPath;
	private boolean isJson;
	private boolean isHtml;
	private String contName;
	private String actName;
	
	public HTTPServletRequest(HTTPContext httpContext,HttpServletRequest request,HTTPSession session){
		delegate = request;
		isJson = jsonPattern.matcher(request.getServletPath()).find();
		isHtml = htmlPattern.matcher(request.getServletPath()).find();
		trimPath = request.getServletPath().replaceAll("^/|\\.\\w+$", "");
		String[] parts = trimPath.split("/");
		if(parts.length == 2){
			contName = parts[0];
			actName = parts[1];
		}else if(parts.length == 1){
			//contName = XSRules.applicationControllerName;
			contName = "";
			actName = parts[0];
		}
		
		this.httpContext = httpContext;
		this.params = Params.params(request);
		this.session = session;
	}
	
	public HTTPContext httpContext(){
		return httpContext;
	}
	
	@Override
	public String contextPath() {
		return httpContext.contentPath();
	}

	@Override
	public String getAuthType() {
		return delegate.getAuthType();
	}

	@Override
	public String getContextPath() {
		return contextPath();
	}

	@Override
	public String getHeader(String name) {
		return getDelegate().getHeader(name);
	}
	public boolean GET(){
		return getMethod().equalsIgnoreCase("GET");
	}
	public boolean POST(){
		return getMethod().equalsIgnoreCase("POST");
	}
	@Override
	public String getMethod() {
		return delegate.getMethod();
	}

	@Override
	public String getPath() {
		return delegate.getServletPath();
	}

	@Override
	public String getPathInfo() {
		return delegate.getPathInfo();
	}

	@Override
	public String getQueryString() {
		return delegate.getQueryString();
	}

	@Override
	public String getRequestURI() {
		return delegate.getRequestURI();
	}

 

	@Override
	public HTTPHeader header(String name) {
		return HTTPHeader.create(name,delegate.getHeader(name));
	}

	@Override
	public List<HTTPHeader> headers() {
		if(httpHeaders == null){
			List<HTTPHeader> res = new ArrayList<HTTPHeader>();
			Enumeration<String> names = delegate.getHeaderNames();
			while(names.hasMoreElements()){
				String name = names.nextElement();
				HTTPHeader h = HTTPHeader.create(name, delegate.getHeader(name));
				if(h !=null){
					res.add(h);
				}
			}
			httpHeaders =  Collections.unmodifiableList(res);
		}
		return httpHeaders;
	}

	public List<HTTPHeader> headers(String name){
		List<HTTPHeader> res = new ArrayList<HTTPHeader>();
		for(HTTPHeader header : headers()){
			if(header.name().equals(name)){
				res.add(header);
			}
		}
		return Collections.unmodifiableList(res);
	}
	
	 

	@Override
	public boolean isUserInRole(String role) {
		return delegate.isUserInRole(role);
	}

	@Override
	public String uri() {
		return url();
	}

	@Override
	public String url() {
		return delegate.getServletPath();
	}

	 

	@Override
	public HttpServletRequest getDelegate() {
		return delegate;
	}

	@Override
	public boolean hasSessionId() {
		return delegate.isRequestedSessionIdFromURL();
	}

	@Override
	public boolean isSessionIdValid() {
		return delegate.isRequestedSessionIdValid();
	}

	@Override
	public String sessionId() {
		return delegate.getRequestedSessionId();
	}

	@Override
	public HTTPSession session() {
		return session;
	}

	@Override
	public HTTPSession session(boolean create) {
		if(delegate.getSession() == null){
			session = new HTTPServletSession(delegate.getSession(true));
		}
		return session;
	}

	@Override
	public HTTPCookie cookie(String name) {
		for(HTTPCookie hc : cookies()){
			if(hc.name.equals(name)){
				return hc;
			}
		}
		return null;
	}

	@Override
	public List<HTTPCookie> cookies() {
		if(httpCookies == null){
			List<HTTPCookie> rs = new ArrayList<HTTPCookie>();
			Cookie[] cs = delegate.getCookies();
			for(Cookie c : cs){
				rs.add(new HTTPCookie(c.getName(), c.getValue(), c.getDomain(), c.getPath(), c.getMaxAge(), c.getVersion(), c.getSecure()));
			}
			httpCookies =  Collections.unmodifiableList(rs);
		}
		return httpCookies;
	}

	@Override
	public Map<String, Object> params() {
		Map<String, Object> p = new HashMap<String, Object>();
		for(Map.Entry<String, Object> entry: params.entrySet()){
			p.put(entry.getKey(), entry.getValue());
		}
		return p;
	}

	@Override
	public String tirmPath() {
		return trimPath;
	}

	@Override
	public boolean isHtml() {
		return isHtml;
	}

	@Override
	public boolean isJson() {
		return isJson;
	}

	@Override
	public String actionName() {
		return actName;
	}

	@Override
	public String controllerName() {
		return contName;
	}

}
